import datetime
import time

import WorkerBase
import MSLogger
import MSData

import pymssql
import pdb

def getTimeRange(LastEvent):
    now     = datetime.datetime.fromtimestamp(time.time())
    last    = now
    if LastEvent != None:
        last = LastEvent
    begin   = last - datetime.timedelta(hours=1)
    delta   = datetime.timedelta(days=1)
    end     = begin + delta
    tr = (begin.strftime(MSData.TIME_FORMAT_MAGICDB), end.strftime(MSData.TIME_FORMAT_MAGICDB))
    MSLogger.logDebug('WorkerBase::getBeginEnd: LastEvent(%s) TimeRange(%s-%s)' % (str(LastEvent), str(tr[0]), str(tr[1])))
    return tr

class Worker(WorkerBase.WorkerBase):
    def __init__(self, Host, Port, DatabaseName, User, Password):
        self.DBHost = Host
        self.DBPort = Port
        self.DBName = DatabaseName
        self.DBUser = User
        self.DBPass = Password
        self.connection = None

    def getConnectionName(self):
        return '(MSSQL:%s:%s:%s)' % (str(self.DBHost), str(self.DBPort), str(self.DBName))
        
    def getConnection(self):
        return pymssql.connect(host=self.DBHost + ':' + self.DBPort,
                               database=self.DBName, user=self.DBUser, password=self.DBPass)

    def isConnectionGood(self):
        if self.connection:
            return True
        return False
        

    def parseEventPGSM(self, EventTuple):
        e = {}
        e['type']       = EventTuple[2]
        e['datetime']   = EventTuple[1].strftime(MSData.TIME_FORMAT_MAGIC)
        e['savetime']   = EventTuple[4].strftime(MSData.TIME_FORMAT_MAGIC)
        return e

    def parseEventContactId(self, EventTuple):
        e = {}
        cid = ''
        for i in EventTuple[2]:
            t = str(hex(ord(i)))
            if len(t) == 3:
                t = '0%s' % (t[2])
            else:
                t = '%s%s' % (t[2], t[3])
            cid += t
        e['value']  = cid
        e['date']   = EventTuple[1].strftime(MSData.TIME_FORMAT_MAGIC)
        return e

    def parseEventBolid(self, EventTuple):
        e = {}
        e['type']  = EventTuple[2]
        e['datetime']   = EventTuple[1].strftime(MSData.TIME_FORMAT_MAGIC)
        return e

    def parseEventGPS(self, EventTuple):
        e = {}
        e['date']   = EventTuple[1].strftime(MSData.TIME_FORMAT_MAGIC)
        e['lat']    = EventTuple[2]
        e['lon']    = EventTuple[3]
        e['speed']  = EventTuple[4]
        return e

    def finalyzeObject(self, MSObject):
        timeRange   = getTimeRange(MSObject.lastEvent_ContactId)
        
        if len(MSObject.eventIDS) > 0:
            MAX_IDS_CHUNK=100
            curStartIdx = 0
            while True:
                ids = MSObject.eventIDS[curStartIdx:curStartIdx+MAX_IDS_CHUNK]
                if len(ids) <= 0: break
                idsStr = 'eventId=%s' % (str(ids[0]))
                for id in ids[1:len(ids)]:
                    idsStr += 'OR eventId=%s' % (str(id))
                idsStr = idsStr.replace('eventId', 'id')
                query_upd   = "UPDATE _event_data_internal SET inFavourite='True' WHERE (%s)" % (str(idsStr))

                self.connect()
                cursor      = self.connection.cursor()
                cursor.execute(query_upd)
                self.connection.commit()
		MSLogger.logDebug('Worker::finalyze: done %d ids' % (len(ids)))

                curStartIdx += MAX_IDS_CHUNK
                if len(ids) == MAX_IDS_CHUNK: continue
                break

        if MSObject.canClearPGSMEvents: 
            MSObject.canClearPGSMEvents = False
            MSObject.eventsPGSM = []
        if MSObject.canClearContactIdEvents:
            MSObject.canClearContactIdEvents = False
            MSObject.eventsContactId = []
        if MSObject.canClearBolidEvents:
            MSObject.canClearBolidEvents = False
            MSObject.eventsBolid = []


#TPA PGSM and ContactId should be processed in a pair - obligatory

    def getEventsPGSM(self, MSObject):
        self.connect()
        timeRange   = getTimeRange(MSObject.lastEvent_PGSM)
        cursor      = self.connection.cursor()
        query       = "SELECT deviceId,eventTime,type,id,SaveTime FROM _event_data_internal WHERE eventTime>'%s' AND deviceId=%s AND inFavourite='False'" % (str(timeRange[0]), str(MSObject.objectMSId))
        cursor.execute(query)
        data = cursor.fetchall()
        MSObject.eventIDS = []
        for e in data:
		    MSObject.eventIDS.append(e[3])
        return data
        

    def processEventsPGSM(self, MSObject, Events):
        doneNum = 0
        for s in Events:
            try:
                e = MSData.MSEvent()
                t = self.parseEventPGSM(s)
                if MSObject.allowINPUT1: e.fromPGSM_INPUT1(t)
                else: e.fromPGSM(s)
                e.objectId = MSObject.objectPCNId
                MSObject.eventsPGSM.append(e)
                MSObject.lastEvent_PGSM = e.eventReceiveTime
                doneNum += 1
            except Exception, err:
                MSLogger.logDebug('Worker::processEventsPGSM: event(%s) error(%s)' % (str(s), str(err)))
                continue
        return doneNum

    def getEventsContactId(self, MSObject):
        self.connect()
        timeRange   = getTimeRange(MSObject.lastEvent_ContactId)
        cursor      = self.connection.cursor()

        data = []
        if len(MSObject.eventIDS) > 0:
            IDS_STR = 'eventId=%s' % (str(MSObject.eventIDS[0]))
            for id in MSObject.eventIDS[1:len(MSObject.eventIDS)]:
                IDS_STR += 'OR eventId=%s' % (str(id))

            query       = "SELECT deviceId,eventTime,contactData FROM _contactId_data_internal WHERE (%s)" % (str(IDS_STR))
            cursor.execute(query)
            data = cursor.fetchall()

        return data

    def processEventsContactId(self, MSObject, Events):
        doneNum = 0
        for s in Events:
            try:
                e = MSData.MSEvent()
                e.fromContactId(self.parseEventContactId(s))
                e.objectId = MSObject.objectPCNId
                MSObject.eventsContactId.append(e)
                MSObject.lastEvent_ContactId = e.eventReceiveTime
                doneNum += 1
            except Exception, err:
                MSLogger.logDebug('Worker::parseEventContactId: event(%s) error(%s)' % (str(s), str(err)))
                continue
        return doneNum

    def getEventsBolid(self, MSObject):
        self.connect()
        timeRange   = getTimeRange(MSObject.lastEvent_ContactId)
        cursor      = self.connection.cursor()

        data = []
        if len(MSObject.eventIDS) > 0:
            IDS_STR = 'eventId=%s' % (str(MSObject.eventIDS[0]))
            for id in MSObject.eventIDS[1:len(MSObject.eventIDS)]:
                IDS_STR += 'OR eventId=%s' % (str(id))

            query       = "SELECT deviceId,eventTime,rs232str FROM _rs232_data WHERE (%s)" % (str(IDS_STR))
            cursor.execute(query)
            data = cursor.fetchall()
        
        return data

    def processEventsBolid(self, MSObject, Events):
        doneNum = 0
        for s in Events:
            try:
                e = MSData.MSEvent()
                e.fromBolid(self.parseEventBolid(s))
                e.objectId = MSObject.objectPCNId
                MSObject.eventsBolid.append(e)
                MSObject.lastEvent_Bolid = e.eventReceiveTime
                doneNum += 1
            except Exception, err:
                MSLogger.logDebug('Worker::parseEventBolid: event(%s) error(%s)' % (str(s), str(err)))
                continue
        return doneNum


    '''
    def getEventsGPS(self, MSObject):
        self.connect()
        timeRange   = getTimeRange(MSObject.lastEvent_GPS)
        cursor      = self.connection.cursor()

        query_ids   = "SELECT id FROM _event_data_internal WHERE eventTime>'%s' AND deviceId=%s AND inFavourite='False'" % (str(timeRange[0]), str(MSObject.objectMSId))
        cursor.execute(query_ids)
        data = cursor.fetchall()
        
        if len(data) > 0:
            IDS_STR = 'eventId=%s' % (str(data[0][0]))
            for id in data[1:len(data)]:
                IDS_STR += 'OR eventId=%s' % (str(id[0]))

            query       = "SELECT deviceId,eventTime,latitude,longitude,speed FROM _gps_data_internal WHERE (%s)" % (str(IDS_STR))
            cursor.execute(query)
            data = cursor.fetchall()

        return data

    def processEventsGPS(self, MSObject, Events):
        doneNum = 0
        for s in Events:
            try:
                e = MSData.MSEvent()
                e.fromGPSPoint(self.parseEventGPS(s))
                e.objectId = MSObject.objectPCNId
                MSObject.eventsGPS.append(e)
                MSObject.lastEvent_GPS = e.eventReceiveTime
                doneNum += 1
            except Exception, err:
                MSLogger.logDebug('Worker::parseEventGPS: event(%s) error(%s)' % (str(s), str(err)))
                continue
    '''
